﻿using System;
using System.Text;
using AppPort;
using TI;
using System.Threading;
using System.IO;
using System.Web;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Controllers.AdministrationControllerCommands
{
    
    public class inOpenHtmlDocument
    {
        public string DocID { get; set; }
        public int Part { get; set; }
        public long iTransportDay { get; set; }
        public string FullID { get; set; }
        public string PublicFileName { get; set; }
        public List<string> Tags { get; set; } 
        public DateTime dTransportDay { get { return Helper.Time.GetDate(iTransportDay); } }
    }      

    //инкапсулирует опреацию по конвертации документа в HTML
    public class OpenHtmlDocument
    {
        const string startJS="<script language='javascript' type='text/javascript'>    Ext.onReady(function () {Ext.BLANK_IMAGE_URL = 'images/s.gif';Ext.QuickTips.init(); Main();});    </script>";
        const string varJS = "<script language='javascript' type='text/javascript'>  var lastKeyWordID=null;   </script>";
        const string templVarsJS = "<script language='javascript' type='text/javascript'>    var DocID='{0}'; var Part={1}; </script>";
        const string extJS="<script src='../../ext-4.0.7-gpl/ext-all-debug.js' type='text/javascript'></script>" ;
        const string extCss = "<link href='../../ext-4.0.7-gpl/resources/css/ext-all-gray.css' rel='stylesheet' type='text/css' />";
        const string appCss = "<link href='../../editorstyle.css' rel='stylesheet' type='text/css' />";

        const string globalVars = "<script type='text/javascript' src='../../Scripts/global.js'></script>";
        const string featurejs = "<script type='text/javascript' src='../../Scripts/featurejs.js'></script>";
        const string docModel = "<script src='../../Scripts/DocumentEditor/documentModel.js' type='text/javascript'></script>";
        const string docEditor = "<script src='../../Scripts/DocumentEditor/documentEditorExt.js' type='text/javascript'></script>";        
        const string rowEditor = "<script src='../../Scripts/DocumentEditor/window.DocumentRowEditor.js' type='text/javascript'></script>";
        const string gridRowEditor = "<script src='../../Scripts/DocumentEditor/grid.DocumentRowEditor.js' type='text/javascript'></script>";
        
        
        static AutoResetEvent autoEvent;
        
        public static  string Run(ServiceCmd cmd)
        {
            inOpenHtmlDocument inP = Helper.Json<inOpenHtmlDocument>.NewtonDeserializeObject(cmd.args.ToString ());

            autoEvent = new AutoResetEvent(false);
            
            //файл существует?
            if (File.Exists(PopulateDayHtml.GetHtmFileName(inP.dTransportDay, inP.FullID)))
                return "{success:true,result:{url:'" + GetHtmFileURL(inP.dTransportDay, inP.FullID) + "'},}";

            //файл не существует формируем
            PopulateDayHtml.CreateHtmlItem(inP.dTransportDay, inP.PublicFileName, inP.FullID, CreateHtmlItem_Exited);  
            autoEvent.WaitOne();

            string fileName=PopulateDayHtml.GetHtmFileName(inP.dTransportDay, inP.FullID);
            string url = HttpContext.Current.Server + fileName; 
            PopulateJS(fileName,inP);

            return "{success:true,result:{url:'" +GetHtmFileURL(inP.dTransportDay, inP.FullID) + "'},}";
        }

        private static string GetHtmFileURL(DateTime Day, string FullID)
        {
            return "/Html/"+Day.ToShortDateString() + @"/" + FullID + ".html";

        }

        private static void PopulateJS(string fileName, inOpenHtmlDocument inP)
        {
            StringBuilder sb = ReadAndInjectScriptAndKeyWords(fileName, inP, "'ModeEng.CellClick(cellid);' ");

            SaveToFile(sb.ToString(), fileName); 
        }

        private static void SaveToFile(string html, string fileName)
        {
            System.IO.TextWriter w = new System.IO.StreamWriter(fileName, false, Encoding.GetEncoding(1251));
            w.Write(html);
            w.Flush();
            w.Close();
        }

        //считать HTML как текст и вставить скрипты
        private static StringBuilder ReadAndInjectScriptAndKeyWords(string fileName, 
                                                                    inOpenHtmlDocument inP,
                                                                    string TdScript)
        {
            StringBuilder sb = new StringBuilder();
            TextReader reader = new StreamReader(fileName, Encoding.GetEncoding (1251));
            string str=string.Empty ;
            int strCount = 0;
            int tblCount = 0;
            int tblTdCount = 0;
            int tblRowCount = 0;
            string tdID=string.Empty ;
                                  


            string tdScriptCellClick=string.Empty;
            string tdScriptContextClick=string.Empty;
            string tdScriptMouseOver = string.Empty;
            StringBuilder sbTags = new StringBuilder();                        

            string lastKeyWordID ="";
            string currentTableID = "";
            int currentTablePosition = 0;
            Func<string, bool> MarkCurrentTable = delegate(string idPref) { 
                string oldStr ="<TABLE id=" + currentTableID;
                sb.Replace(oldStr, "<TABLE class='keyTable' id="+ currentTableID);
                return true; 
            };
            while (reader.Peek() >= 0) 
                {   
                    str=reader.ReadLine();
                 
                    if (str.IndexOf("<HEAD>") > -1)
                    {
                        sb.Append(extCss);
                        sb.Append(appCss);
                        sb.Append(extJS);
                        sb.Append(docModel);
                        sb.Append(docEditor);                       
                        sb.Append(rowEditor);
                        sb.Append(gridRowEditor);                        
                        sb.Append(string.Format(templVarsJS,inP.DocID ,inP.Part));
                        sb.Append(featurejs);
                        sb.Append(startJS);
                        sb.Append(varJS); 
                        sb.Append(globalVars); 
                    }

                    
                    if (str.IndexOf("<TITLE") > -1)
                    {
                        sbTags.Clear();
                        foreach (string i in inP.Tags ){
                            sbTags.Append(i + " ");
                        }

                        str = "<TITLE>" + inP.PublicFileName + "(" + sbTags.ToString() + ")" + "</TITLE>";
                    }
                    
                    if (str.IndexOf("<TABLE") > -1)
                    {
                        ++tblCount;

                        tblTdCount = 0;
                        tblRowCount =0;

                        currentTableID = "'" + tblCount.ToString () + "'";
                        str = str.Replace("<TABLE", "<TABLE id=" + currentTableID);
                        
                        currentTablePosition = strCount;
                    }

                    if (str.IndexOf("<TR") > -1)
                    {
                        tblTdCount = 0;
                        ++tblRowCount;
                        str = str.Replace("<TR", "<TR id='" + tblCount.ToString() + "_" + tblRowCount + "' ");
                       
                    }
 
                    // подсветка слов    
                    str = BackLigthKeyWords(str, inP.Tags, strCount, ref lastKeyWordID, MarkCurrentTable);
                    

                    //выставить реакцию TD click
                    
                    if (str.IndexOf("<TD ") > -1)
                    {
                        tdID=tblCount.ToString() +"_"+tblRowCount.ToString() + "_" + tblTdCount.ToString();
                        tdScriptCellClick = "'TdTableEventHandler.CellClick(\"" + tdID + "\")';";
                        tdScriptContextClick = "'TdTableEventHandler.ContextClick(\"" + tdID + "\")';";
                        tdScriptMouseOver = "'TdTableEventHandler.OnmouseOver(\"" + tdID + "\")';";
                        str = str.Replace("<TD ", "<TD onmouseover="+tdScriptMouseOver+" oncontextmenu="+ tdScriptContextClick +" id='" + tdID + "' onclick=" + tdScriptCellClick);
                        ++tblTdCount;
                    }
                    sb.AppendLine(str);
                    ++strCount;
            }

            sb.Replace("lastKeyWordID=null", "lastKeyWordID='" + lastKeyWordID + "'");
            reader.Close();

            // прописать идентификацию td по правилам excel
            TableParser p = new TableParser(sb.ToString ());
            
            return sb;
        }

        //подсветить ключевые слова в строке
        private static string BackLigthKeyWords(string str, List<string> keyWords, int strNumber, ref string  lastKeyWordID,Func<string, bool> callMarkCssCurrentTable)
        {
            for(int i=0;i<keyWords.Count;i++) 
            {
                if(str.IndexOf (keyWords[i],StringComparison.InvariantCultureIgnoreCase)>-1){
                    lastKeyWordID = "kw"+ i.ToString() + "_" + strNumber.ToString();
                    str = str.Replace(keyWords[i], "<SPAN id=" + lastKeyWordID + " class='keyWord'>" + keyWords[i] + "</SPAN>");
                    callMarkCssCurrentTable(lastKeyWordID); 
                }
            }
            return str;
        }

        private static void CreateHtmlItem_Exited(object Sender, EventArgs e)
        {
            autoEvent.Set () ;
        }
     
    }

    
    //проставить td_click всем табличкам документа
    public class TableParser {
        string fileContent = string.Empty;

        // первичное состояние html являющееся табличками
        List<string> etalonTableContent = new List<string>();

        // состояние после именения
        List<string> changedTableContent = new List<string>();

       
        public TableParser(string fileContent) {
            this.fileContent = fileContent;
            PopulateTable();
        }

        public void PopulateTable()
        {
            string table_pattern = "<TABLE.*?>(.*)</TABLE>";
            MatchCollection table_matches = Regex.Matches(fileContent, table_pattern, RegexOptions.Singleline);
            foreach (Match match in table_matches)
                etalonTableContent.Add(match.Value);
        }

        public  void  SetTdClick(StringBuilder html, string clickScript){
            
       }
    }
}
